<?php declare(strict_types=1);

namespace app\admin\service;

use app\admin\model\Menu;

class MenuService
{
    /**
     * @return void
     */
    public function getMenuList()
    {
        $userInfo = session('{ADMIN_LOGIN_INFO}');
        $userId = $userInfo['admin_id'];
        $whereFunction = function ($query) use ($userId, $userInfo) {
            if (isset($userInfo['role_id']) && $userInfo['role_id']) {
                $roleId = $userInfo['role_id'];
                if ($userId <> 1 && $roleId <> 1) {
                    $ids = (new RoleService())->getUserPermissionIds($userInfo['role_id']);
                    $query->whereIn('id', explode(',', (string)$ids));
                }
            }
        };
        $model = new Menu();
        $menuList = $model->where("status", "=", 1)
            ->where('is_display', 1)
            ->where($whereFunction)
            ->order(['sort'=>'asc','create_time'=>'asc'])
            ->select()
            ->toArray();
        if (!empty($menuList)) {
            foreach ($menuList as $key => $value) {
                if(empty($value['parameter'])) {
                    $url = url($value['module'].'/'.$value['controller'].'/'.$value['function']);
                } else {
                    $url = url($value['module'].'/'.$value['controller'].'/'.$value['function'].','.$value['parameter']);
                }
                if($url == '/'){
                    $url = '';
                }
                $menuList[$key]['url'] = $url;
            }
            $menuList = $this->_formatMenu($menuList);
        }
        return $menuList;
    }

    /**
     * 获取角色对应菜单
     * @param $roleId
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserMenuList($roleId)
    {
        $ids = (new RoleService())->getUserPermissionIds($roleId);
        if (!$ids) {
            return [];
        }
        $whereFunction = function ($query) use ($ids) {
            $query->whereIn('id', explode(',', (string)$ids));
        };
        $model = new Menu();
        $menuList = $model->where("status", "=", 1)
            ->field(['id','name as title','pid'])
            ->where('is_display', 1)
            ->where($whereFunction)
            ->order(['sort'=>'asc','create_time'=>'asc'])
            ->select()
            ->toArray();
        if (!empty($menuList)) {
            $menuList = $this->_formatSystemMenuByChecked(explode(',', (string)$ids), $menuList);
        }
        return $menuList;
    }

    /**
     * 格式化菜单
     * @param array $menuList
     * @return void
     */
    public function _formatMenu(array $menuList, $id = 0, $level = 0)
    {
        $menus = [];
        foreach ($menuList as $menu) {
            if($menu['pid'] == $id) {
                $menu['level'] = $level;
                $str = '';
                for ($i=0; $i<$level; $i++) {
                    $str .= "--";
                }
                $menu['level_name'] = $str.' '.$menu['name'];
                // 递归调用
                $menu['children'] = $this->_formatMenu($menuList, $menu['id'], $level + 1);
                if (empty($menu['children'])) {
                    unset($menu['children']);
                }
                $menus[] = $menu;
            }
        }
        return $menus;
    }

    /**
     * 系统菜单列表
     * @return void
     */
    public function getSystemMenu()
    {
        $model = new Menu();
        $items = $model->where("status",1)
            ->where('is_display', 1)
            ->field(['id','name as title','pid'])
            ->order(['sort'=>'desc','create_time'=>'asc'])
            ->select()
            ->toArray();
        if (!empty($items)) {
            $items = $this->_formatSystemMenu($items);
        }
        return $items;
    }

    /**
     * 格式化系统菜单（分配权限）
     * @param $items
     * @param $id
     * @param $level
     * @return array
     */
    public function _formatSystemMenu($items, $id = 0, $level = 0){

//        $menus = [];
//        foreach ($items as $menu) {
//            if($menu['pid'] == $id) {
//                $menu['level'] = $level;
//                // 递归调用
//                $menu['children'] = $this->_formatSystemMenu($items, $menu['id'], $level + 1);
//                if (empty($menu['children'])) {
//                    unset($menu['children']);
//                }
//                $menus[] = $menu;
//            }
//        }
        $data = [];
        foreach ($items as $item) {
            if ($item['pid'] == 0) {
                $item['spread'] = true;
            }
            if($item['pid'] == $id) {
                //$item['level'] = $level;
                $item['spread'] = true;
                // 递归调用
                $item['children'] = $this->_formatSystemMenu($items, $item['id'], $level + 1);
                if (empty($item['children'])) {
                    unset($item['children']);
                }
                $data[] = $item;
            }
        }
        return $data;
    }

    /**
     * 格式化系统菜单（是否选中）
     * @param $items
     * @param int $id
     * @param int $level
     * @return array
     */
    public function _formatSystemMenuByChecked($permissionIds, $items, $id = 0, $level=0): array
    {
        $data = [];
        if (!$permissionIds) {
            return [];
        }
        foreach ($items as $item) {
            if ($item['pid'] == 0) {
                $item['spread'] = true;
            }
            if ($item['pid'] == $id) {
                $item['spread'] = true;
                // 递归调用
                $item['children'] = $this->_formatSystemMenuByChecked($permissionIds, $items, $item['id'], $level + 1);
                if (empty($item['children'])) {
                    unset($item['children']);
                }
                if (in_array($item['id'], $permissionIds) && empty($item['children'])) {
                    $item['checked'] = true;
                }
                $data[] = $item;
            }
        }
        return $data;
    }
}